package craky.keeper.client;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import craky.keeper.bean.User;
import craky.keeper.client.task.LoginTask;
import craky.keeper.util.DBUtil;
import craky.keeper.util.KeeperUtil;
import craky.keeper.view.GlassView;
import craky.keeper.view.GradientPaintRelativeLayout;
import craky.keeper.view.ToastView;
import craky.util.Util;

public class LoginActivity extends Activity
{
    private static final String LOGIN_PREF_KEY = "login_pref";

    private static final String IP_KEY = "Server_IP";

    private static final String USERNAME_KEY = "Username";

    private GradientPaintRelativeLayout content;

    private LinearLayout loginInput;

    private ImageView logoView;

    private EditText txtIp, txtUsername, txtPassword;

    private EditText[] inputs;

    private ToastView toast;

    private GlassView glass;

    private InputMethodManager imManager;

    private Resources resources;

    private String[] inputValues;

    private int softInputHeight;

    private long loginTime;

    private boolean softInputHeightInited;

    private LoginTask loginTask;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        KeeperUtil.getDisplayDensity(this);
        imManager = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
        resources = getResources();
        content = (GradientPaintRelativeLayout)findViewById(R.id.content);
        loginInput = (LinearLayout)findViewById(R.id.loginInput);
        logoView = (ImageView)findViewById(R.id.logoView);
        txtIp = (EditText)findViewById(R.id.txtIp);
        txtUsername = (EditText)findViewById(R.id.txtUsername);
        txtPassword = (EditText)findViewById(R.id.txtPassword);
        toast = (ToastView)findViewById(R.id.toast);
        glass = (GlassView)findViewById(R.id.glass);
        inputs = new EditText[]{txtIp, txtUsername, txtPassword};
        loginInput.post(new Runnable()
        {
            public void run()
            {
                logoViewAnimationAction();
                loginInputAnimationAction();
            }
        });
        content.addOnLayoutChangeListener(new View.OnLayoutChangeListener()
        {
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)
            {
                resetLoginInputY();
            }
        });
        content.setOnTouchListener(new View.OnTouchListener()
        {
            public boolean onTouch(View v, MotionEvent event)
            {
                hideOrShowSoftInput(null);
                return false;
            }
        });
        txtUsername.addTextChangedListener(new TextWatcher()
        {
            public void onTextChanged(CharSequence s, int start, int before, int count)
            {}

            public void beforeTextChanged(CharSequence s, int start, int count, int after)
            {}

            public void afterTextChanged(Editable s)
            {
                txtPassword.setText(null);
            }
        });
        loadLoginHistory();
        requestInputFocus();
    }

    @Override
    protected void onPause()
    {
        cancelLogin();
        super.onPause();
    }

    @Override
    public void onBackPressed()
    {
        if(glass.getVisibility() == View.VISIBLE)
        {
            cancelLogin();
        }
        else
        {
            DBUtil.closeConnection();
            KeeperUtil.remote = null;
            super.onBackPressed();
        }
    }

    private void logoViewAnimationAction()
    {
        Animation animation = new AlphaAnimation(0.0f, 1.0f);
        animation.setDuration(500);
        logoView.startAnimation(animation);
    }

    private void loginInputAnimationAction()
    {
        int animationType = Animation.RELATIVE_TO_SELF;
        Animation animation = new TranslateAnimation(animationType, 0.0f, animationType, 0.0f, animationType, 1.0f, animationType, 0.0f);
        animation.setDuration(500);
        animation.setInterpolator(new DecelerateInterpolator());
        loginInput.startAnimation(animation);
        loginInput.setVisibility(View.VISIBLE);
    }

    private void resetLoginInputY()
    {
        Rect visibleRect = new Rect();
        content.getWindowVisibleDisplayFrame(visibleRect);

        if(softInputHeight == 0)
        {
            softInputHeight = visibleRect.bottom;
        }
        else if(!softInputHeightInited && softInputHeight > visibleRect.bottom)
        {
            softInputHeight -= visibleRect.bottom;
            softInputHeightInited = true;
        }

        if(softInputHeightInited)
        {
            int deltaHeight = visibleRect.bottom - (loginInput.getBottom() + visibleRect.top);
            deltaHeight = Math.min(0, deltaHeight);
            logoView.offsetTopAndBottom(deltaHeight);
            loginInput.offsetTopAndBottom(deltaHeight);
        }
    }

    private void hideOrShowSoftInput(View view)
    {
        if(view == null)
        {
            imManager.hideSoftInputFromWindow(content.getWindowToken(), 0);
        }
        else
        {
            imManager.showSoftInput(view, InputMethodManager.SHOW_FORCED);
        }
    }

    private boolean validateInput()
    {
        boolean pass = true;
        int[] infoIds = {R.string.input_ip, R.string.input_username, R.string.input_password};
        int count = inputs.length;
        inputValues = new String[count];
        EditText focusNeededInput = null;

        for(int i = 0; i < count; i++)
        {
            if((inputValues[i] = inputs[i].getText().toString()).length() == 0)
            {
                pass = false;
                focusNeededInput = inputs[i];
                toast.showToast(R.drawable.toast_icon_w, resources.getString(infoIds[i]));
                break;
            }
        }

        if(pass)
        {
            if(!Util.checkIPV4(inputValues[0]))
            {
                pass = false;
                focusNeededInput = txtIp;
                toast.showToast(R.drawable.toast_icon_w, resources.getString(R.string.ip_incorrect));
            }
            else if(inputValues[2].length() < 4)
            {
                pass = false;
                focusNeededInput = txtPassword;
                toast.showToast(R.drawable.toast_icon_w, resources.getString(R.string.password_too_short));
            }
        }

        if(focusNeededInput != null)
        {
            focusNeededInput.requestFocus();
            hideOrShowSoftInput(focusNeededInput);
        }

        return pass;
    }

    private void cancelLogin()
    {
        if(loginTask != null && loginTask.getStatus() != AsyncTask.Status.FINISHED)
        {
            loginTask.cancel(false);
            dealLoginResult(loginTask, null, null);
        }
    }

    public void login(View view)
    {
        if(validateInput())
        {
            hideOrShowSoftInput(null);
            content.requestFocus();
            toast.hideToastImmediately();
            glass.setVisibility(View.VISIBLE);
            toast.startTask(R.drawable.loading, resources.getString(R.string.logining));
            loginTask = new LoginTask(this, loginTime = System.currentTimeMillis());
            loginTask.execute(inputValues);
        }
    }

    public void dealLoginResult(LoginTask task, String errorMessage, User user)
    {
        if(this.loginTime == task.getLoginTime())
        {
            //Login success
            if(user != null)
            {
                this.finish();
                Intent intent = new Intent(this, KeeperActivity.class);
                startActivity(intent);
            }
            else
            {
                toast.stopTask();
                glass.setVisibility(View.INVISIBLE);

                if(errorMessage != null && !errorMessage.isEmpty())
                {
                    toast.showToast(R.drawable.toast_icon_w, errorMessage);
                }
            }
        }

        loginTime = 0;
    }

    private void requestInputFocus()
    {
        for(EditText input: inputs)
        {
            if(input.getText().length() == 0)
            {
                input.requestFocus();
                break;
            }
        }
    }

    private void loadLoginHistory()
    {
        SharedPreferences preferences = this.getSharedPreferences(LOGIN_PREF_KEY, MODE_PRIVATE);

        if(preferences != null)
        {
            txtIp.setText(preferences.getString(IP_KEY, null));
            txtUsername.setText(preferences.getString(USERNAME_KEY, null));
        }
    }

    public void saveLoginHistory()
    {
        SharedPreferences preferences = this.getSharedPreferences(LOGIN_PREF_KEY, MODE_PRIVATE);
        SharedPreferences.Editor editor = preferences.edit();
        editor.putString(IP_KEY, KeeperUtil.currentIp);
        editor.putString(USERNAME_KEY, KeeperUtil.currentUser.getName());
        editor.commit();
    }
}